package com.chj.producers;

import com.chj.beans.vo.MessageVo;
import com.chj.utils.JsonUtil;
import com.chj.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Slf4j
public class RabbitMQProducer {

    private static RabbitMQProducer instance;

    private RabbitAdmin rabbitAdmin;
    private RabbitTemplate template;

    public RabbitMQProducer() {
        this.rabbitAdmin = SpringContextUtil.getBean(RabbitAdmin.class);
        this.template = SpringContextUtil.getBean(RabbitTemplate.class);
        // publisher-confirm 用来确认发送消息状态，当ack状态为false时表示消息没有被server确认，需要实现对应处理逻辑
        if (!template.isConfirmListener()) {
            template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
                public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                    if (ack) {
                        log.info(" ********** ack: " + ack + ". correlationData: " + correlationData + "cause : " + cause);
                    } else {
                        /** 消息确认处理逻辑实现 */
                    }
                }
            });
        }
    }

    public static RabbitMQProducer getInstance() {
        if (instance == null) {
            instance = new RabbitMQProducer();
        }
        return instance;
    }

    public void sendMQMsg(MessageVo message) {
        log.info(" ********** Sent MessageVo = {}'", JsonUtil.getJson(message));
        bindingBuilder(message);
        String messageStr = JsonUtil.getJson(message.getMessageContent());
        template.convertAndSend(message.getExchangeName(), message.getRouteKey(), messageStr, new CorrelationData(UUID.randomUUID().toString()));
        // 不一定UUID，但要注意CorrelationData的全局唯一
        log.info(" ********** Sent '" + messageStr + "'");
    }

    private void bindingBuilder(MessageVo message) {
        TopicExchange exchange = (TopicExchange) ExchangeBuilder.topicExchange(message.getExchangeName()).durable(true).build();
        // Queue queue = QueueBuilder.durable(queueName).build();
        // Binding binding = BindingBuilder.bind(queue).to(exchange).with(message.getRouteKey());// 将queue绑定到exchange
        rabbitAdmin.declareExchange(exchange);
        // rabbitAdmin.declareQueue(queue);
        // rabbitAdmin.declareBinding(binding);// 声明绑定关系
    }
}
